package com.lyc.iotdb.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.lyc.iotdb.common.component.FlashSqlEngineTool;
import com.lyc.iotdb.common.iot.IotdbPage;
import com.lyc.iotdb.common.iot.IotdbSessionConfig;
import com.lyc.iotdb.common.utils.Constant;
import com.lyc.iotdb.common.utils.IotdbTableParam;
import com.lyc.iotdb.common.utils.Rst;
import com.lyc.iotdb.entity.WeatherEntity;
import com.lyc.iotdb.mapper.BaseMapper;
import com.lyc.iotdb.mapper.WeatherMapper;
import com.lyc.iotdb.service.WeatherService;
import lombok.extern.slf4j.Slf4j;
import org.apache.iotdb.rpc.IoTDBConnectionException;
import org.apache.iotdb.rpc.StatementExecutionException;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.RoundingMode;
import java.util.Date;
import java.util.Map;

/**
 * 添加说明
 *
 * @author kisang
 * @version 1.0
 * @date 2023/11/28 9:48
 */
@Slf4j
@Service
public class WeatherServiceImpl implements WeatherService {
    @Resource
    private IotdbSessionConfig iotdbSessionConfig;

    @Resource
    private FlashSqlEngineTool flashSqlEngineTool;

    @Resource
    private WeatherMapper weatherMapper;

    /**
     * 插入数据
     *
     * @param weather 数据
     * @return rst
     */
    @Override
    public Rst save(WeatherEntity weather) {
        Date date = new Date();
        if (weather == null || StrUtil.isEmpty(weather.getCity())) {
            int index = RandomUtil.randomInt(0, 11);
            String cityInfo = Constant.CITY_ARY[index];
            String cityName = cityInfo.split(StrUtil.COLON)[0];
            Integer cityKey = Integer.valueOf(cityInfo.split(StrUtil.COLON)[1]);
            // 模拟数据
            weather = WeatherEntity.builder()
                    .samplingTime(date.getTime())
                    .samplingTimeStr(DateUtil.format(date, "yyyy-MM-dd HH:mm:ss"))
                    .cityKey(cityKey)
                    .city(cityName)
                    .temperature(NumberUtil.parseFloat(StrUtil.toString(RandomUtil.randomDouble(-18.2, 30.5, 1, RoundingMode.HALF_UP))))
                    .humidity(NumberUtil.parseFloat(StrUtil.toString(RandomUtil.randomDouble(1, 100, 1, RoundingMode.HALF_UP))))
                    .pm10(NumberUtil.parseFloat(StrUtil.toString(RandomUtil.randomDouble(0, 300, 0, RoundingMode.HALF_UP))))
                    .pm25(NumberUtil.parseFloat(StrUtil.toString(RandomUtil.randomDouble(0, 300, 1, RoundingMode.HALF_UP))))
                    .quality(Constant.QUALITY_OPTIONS[RandomUtil.randomInt(0, 3)])
                    .remark(cityName + "模拟插入").build();
        }
        iotdbSessionConfig.insertRecord(weather);
        return Rst.ok();
    }

    /**
     * 分页查询
     *
     * @param params 查询参数
     * @return rst
     */
    @Override
    public IotdbPage getPageList(Map<String, Object> params) {
        // 第一种方式，通过sql Template 拼接sql语句
        String methodName = BaseMapper.getSqlId(WeatherMapper.class, "getPageList");
        String sql = flashSqlEngineTool.parseSqlWithSqlId(methodName, JSONUtil.parseObj(params));
        log.info("sql {}", sql);
        // 第二种方式，自定义拼接sql
        String sql2 = weatherMapper.getPageList(params);
        log.info("sql2 {}", sql2);
        return iotdbSessionConfig.queryPage(sql2, params, "remark", WeatherEntity.class);
    }

    /**
     * 分页查询Map
     *
     * @param params 查询参数
     * @return rst
     */
    @Override
    public IotdbPage getPageMap(Map<String, Object> params) {
        String methodName = BaseMapper.getSqlId(WeatherMapper.class, "getPageMap");
        String sql = flashSqlEngineTool.parseSqlWithSqlId(methodName, JSONUtil.parseObj(params));
        log.info("sql {}", sql);
        // 第二种方式，自定义拼接sql
        String sql2 = weatherMapper.getPageMap(params);
        log.info("sql2 {}", sql2);
        return iotdbSessionConfig.queryPage(sql2, params, "remark", IotdbTableParam.IOT_TABLE_LN_WEATHER);
    }

    /**
     * 根据时间范围删除数据
     *
     * @param params 参数
     * @return rst
     */
    @Override
    public Rst delete(Map<String, Object> params) {
        String methodName = BaseMapper.getSqlId(WeatherMapper.class, "delete");
        String sql = flashSqlEngineTool.parseSqlWithSqlId(methodName, JSONUtil.parseObj(params));
        log.info("delete sql: {}", sql);
        try {
            iotdbSessionConfig.getSession().executeNonQueryStatement(sql);
        } catch (IoTDBConnectionException | StatementExecutionException e) {
            throw new RuntimeException(e);
        }
        return Rst.ok();
    }
}
